﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;
using System.Threading;

namespace IR
{
    public partial class Form1 : Form
    {
        Indexer m_idx;
        MatchingSystem m_ms;

        DocumentsList m_Docs;
        Thread workerThread;
        Thread updateThread;
        bool needUpdate;
        int currentTab;
        List <ListViewItem> Step1_lvItems;
        List<ListViewItem> Step2_lvItems;
        List<ListViewItem> Step3_lvItems;
       
        

        public delegate void setProgressDelegate();
        public delegate void setlvUpdateDelegate();
        public delegate void setlvUpdateDelegate_strPram(string str);
        
        public Form1()
        {

            InitializeComponent();
            needUpdate = false;


            tm_Work.Interval = 10000;
            tm_Work.Start();
            currentTab = tabControl1.SelectedIndex;
            
            //FileStream fff = new FileStream("debug_ltnlnc.txt", FileMode.Create);
            //StreamWriter sw = new StreamWriter(fff);
            //foreach (Document d in m_Docs)
            //{
            //    sw.WriteLine("번호 " + d.Doc_number + " " + "우선순위 : " + d.Priority + " 문서길이 : " + d.Docs_Length);

            //}
            //sw.Close();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            tm_Work_Tick(sender, e);
            tb_Input.Select();

        }

        private void btn_Search_Click(object sender, EventArgs e)
        {
            Search();

        }

        private void lv_Result_DoubleClick(object sender, EventArgs e)
        {
            string path = lv_Result.FocusedItem.SubItems[3].Text;

            Process p = Process.Start(path);
            p.Close();

        }

        private void tb_Input_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Enter)
            {
                Search();

            }
        }
        private void Search()
        {
            String Query;


            Query = tb_Input.Text;

            if (Query.CompareTo("") == 0)
            {
                MessageBox.Show("검색어를 입력해!");
                return;

            }


            if (m_ms == null || m_ms.Ready == false)
            {

                MessageBox.Show("초기화 중입니다.");
                return;
            }

            m_Docs = m_ms.Retreival(Query);

            lv_Result.BeginUpdate();
            lv_Result.Clear();

            lv_Result.View = View.Details;


            foreach (Document d in m_Docs)
            {
                if (d.Priority > 0.0f)
                {
                    ListViewItem lvItem = new ListViewItem("" + d.Doc_number);
                    lvItem.SubItems.Add("" + d.Priority);
                    lvItem.SubItems.Add(d.Preview);
                    lvItem.SubItems.Add(d.Path);
                    lv_Result.Items.Add(lvItem);
                }


            }
            // 컬럼명과 컬럼사이즈 지정
            
            lv_Result.Columns.Add("Docs", 70, HorizontalAlignment.Left);
            lv_Result.Columns.Add("priority", 190, HorizontalAlignment.Center);
            lv_Result.Columns.Add("Preview", 700, HorizontalAlignment.Left);

            lv_Result.EndUpdate();

        }

        private void tabControl1_Selected(object sender, TabControlEventArgs e)
        {
            currentTab = e.TabPageIndex;

            if (e.TabPageIndex == 0)
            {
                tb_Input.Select();
            }
            else
            {
                if (m_ms == null || m_ms.Ready == false)
                {

                    MessageBox.Show("초기화 중입니다.");
                    return;
                }
                if (updateThread == null || updateThread.ThreadState == System.Threading.ThreadState.Stopped)
                {
                    updateThread = new Thread(UpdateIndexTab);
                    updateThread.Start();

                }
 
            }
        }
#region Update_index_Tab

        private void Update_lv_step1()
        {
            FileStream fstream = new FileStream("debug_step1.txt", FileMode.Open);
            StreamReader fReader = new StreamReader(fstream, Encoding.UTF8);
            string str;
            Step1_lvItems = new List<ListViewItem>();

 
            while (fReader.EndOfStream == false)
            {
                string[] items;
                ListViewItem lvItem;

                str = fReader.ReadLine();
                items = str.Split();


                lvItem = new ListViewItem("" + items[0]);
                lvItem.SubItems.Add("" + items[1]);
                Step1_lvItems.Add(lvItem);
            }
            fstream.Close();
            UpdateView_lv_Step1();
        }

        private void UpdateView_lv_Step1()
        {

            if (this.lv_step1.InvokeRequired)
            {
                setlvUpdateDelegate setproc_delgte = new setlvUpdateDelegate(Update_lv_step1);
                this.Invoke(setproc_delgte);

            }
            else
            {

                lv_step1.BeginUpdate();
                lv_step1.Items.Clear();
                lv_step1.View = View.Details;

                foreach(ListViewItem lvItem in Step1_lvItems)
                {
                    lv_step1.Items.Add(lvItem);

                }
                lv_step1.Columns.Add("Terms", 100, HorizontalAlignment.Left);
                lv_step1.Columns.Add("Doc#", 80, HorizontalAlignment.Center);
                lv_step1.EndUpdate();

            
            }
        }
        private void Update_lv_step2()
        {

            FileStream fstream = new FileStream("debug_step2.txt", FileMode.Open);
            StreamReader fReader = new StreamReader(fstream, Encoding.UTF8);
            string str;

            Step2_lvItems = new List<ListViewItem>();
          

            while (fReader.EndOfStream == false)
            {
                string[] items;
                ListViewItem lvItem;

                str = fReader.ReadLine();
                items = str.Split();


                lvItem = new ListViewItem("" + items[0]);
                lvItem.SubItems.Add("" + items[1]);


                Step2_lvItems.Add(lvItem);
             }
            fstream.Close();
            UpdateView_lv_Step2();

        }

        private void UpdateView_lv_Step2()
        {
            if (this.lv_step2.InvokeRequired)
            {
                setlvUpdateDelegate setproc_delgte = new setlvUpdateDelegate(Update_lv_step2);
                this.Invoke(setproc_delgte);
            }
            else
            {
              
                lv_step2.BeginUpdate();
                lv_step2.Items.Clear();
                lv_step2.View = View.Details;


                foreach (ListViewItem lvItem in Step2_lvItems)
                {
                    lv_step2.Items.Add(lvItem);
                }
                lv_step2.Columns.Add("Terms", 100, HorizontalAlignment.Left);
                lv_step2.Columns.Add("Doc#", 80, HorizontalAlignment.Center);
                lv_step2.EndUpdate();

              
            }
         

        }
        
        private void Update_lv_step3()
        {

            FileStream fstream = new FileStream("debug_step3.txt", FileMode.Open);
            StreamReader fReader = new StreamReader(fstream, Encoding.UTF8);
            string str;
            Step3_lvItems = new List<ListViewItem>();


            while (fReader.EndOfStream == false)
            {
                string[] items;
                ListViewItem lvItem;

                str = fReader.ReadLine();
                items = str.Split();


                lvItem = new ListViewItem("" + items[0]);
                lvItem.SubItems.Add("" + items[1]);
                lvItem.SubItems.Add("" + items[2]);

                Step3_lvItems.Add(lvItem);


            }
 
            fstream.Close();

            UpdateView_lv_Step3();

        }
        private void UpdateView_lv_Step3()
        {

            if (this.lv_step3.InvokeRequired)
            {

                setlvUpdateDelegate setproc_delgte = new setlvUpdateDelegate(Update_lv_step3);
                this.Invoke(setproc_delgte);


            }
            else
            {
               
                lv_step3.BeginUpdate();
                lv_step3.Items.Clear();
                lv_step3.View = View.Details;

                foreach (ListViewItem lvItem in Step3_lvItems)
                {
                    lv_step3.Items.Add(lvItem);
                }
                
                lv_step3.Columns.Add("Terms", 80, HorizontalAlignment.Left);
                lv_step3.Columns.Add("Doc#", 55, HorizontalAlignment.Center);
                lv_step3.Columns.Add("Freq", 50, HorizontalAlignment.Center);

                lv_step3.EndUpdate();

           

            }
        }

        private void Update_lv_step4()
        {

            if (this.lv_step4.InvokeRequired)
            {

                setlvUpdateDelegate setproc_delgte = new setlvUpdateDelegate(Update_lv_step4);
                this.Invoke(setproc_delgte);


            }
            else
            {
            
                lv_step4.BeginUpdate();
                lv_step4.Items.Clear();
                lv_step4.View = View.Details;

                foreach (IR_Dictionary d in m_idx.Index.IR_Dct)
                {

                    ListViewItem lvItem = new ListViewItem("" + d.Term);
                    lvItem.SubItems.Add("" + d.N_Docs);
                    lvItem.SubItems.Add("" + d.Call_freq);

                   
                    lv_step4.Items.Add(lvItem);

                }
                lv_step4.Columns.Add("Terms", 80, HorizontalAlignment.Left);
                lv_step4.Columns.Add("N_Doc", 62, HorizontalAlignment.Center);
                lv_step4.Columns.Add("Call Freq", 50, HorizontalAlignment.Center);

                lv_step4.EndUpdate();

            }
           
        }
       

        private void Update_lv_step4_postings(string term)
        {

            if (this.lv_step4_postings.InvokeRequired)
            {

                setlvUpdateDelegate_strPram setproc_delgte = new setlvUpdateDelegate_strPram(Update_lv_step4_postings);
                this.Invoke(setproc_delgte);

            }
            else
            {
                
                lv_step4_postings.BeginUpdate();
                lv_step4_postings.Clear();
                lv_step4_postings.Items.Clear();
                lv_step4_postings.View = View.Details;

                foreach (IR_Dictionary d in m_idx.Index.IR_Dct)
                {

                    if (term.CompareTo(d.Term) == 0)
                    {

                        foreach (Post p in d.Postings)
                        {
                            ListViewItem lvItem = new ListViewItem("" + p.Doc_number);
                            lvItem.SubItems.Add("" + p.Freq);

                            
                            lv_step4_postings.Items.Add(lvItem);

                        }
                        break;
                    }



                }
                lv_step4_postings.Columns.Add("Doc#", 100, HorizontalAlignment.Left);
                lv_step4_postings.Columns.Add("Freq", 80, HorizontalAlignment.Center);


                lv_step4_postings.EndUpdate();

            }





        }

        private void lv_step4_Click(object sender, EventArgs e)
        {
            Update_lv_step4_postings(lv_step4.FocusedItem.SubItems[0].Text);

        }

        
        private void UpdateIndexTab()
        {
            if (needUpdate == true)
            {
                StartProgress();
                Update_lv_step1();
                Update_lv_step2();
                Update_lv_step3();
                Update_lv_step4();
                EndProgress();

                needUpdate = false;
            }
        }

#endregion
        private void tm_Work_Tick(object sender, EventArgs e)
        {

            if (workerThread == null || workerThread.ThreadState == System.Threading.ThreadState.Stopped)
            {
                workerThread = new Thread(work);
                workerThread.Start();

            }

        }
        public void StartProgress()
        {
            if (this.pb_progress.InvokeRequired)
            {

                setProgressDelegate setproc_delgte = new setProgressDelegate(StartProgress);
                this.Invoke(setproc_delgte);


            }
            else
            {
                //rtb_console.Text = count.ToString() + "번째" + str;
                pb_progress.Visible = true;
            }
        }
        public void EndProgress()
        {
            if (this.pb_progress.InvokeRequired)
            {
                setProgressDelegate setproc_delgte = new setProgressDelegate(EndProgress);
                this.Invoke(setproc_delgte);

            }
            else
            {
                pb_progress.Visible = false;
            }
        }


        private void work()
        {

            if (currentTab == 0 && needUpdate == false)
            {
                Thread thread_work;

                StartProgress();

                m_idx = new Indexer();



                thread_work = new Thread(m_idx.RunIndexer);
                thread_work.Start();
                thread_work.Join();

                while (m_idx.Ready == false)
                    ;
                m_ms = new MatchingSystem(m_idx.Index, m_idx.Num_of_total_docs);


                thread_work = new Thread(m_ms.Init);
                thread_work.Start();
                thread_work.Join();


                EndProgress();
                needUpdate = true;
                Thread.CurrentThread.Abort();
                
            }
           
        }

   


    }
}
